using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace EEst.Tools.VsPackageNMakeAdapter
{
    class XCMakefileTemplate
    {
        #region Input Properties
        public string CYGWIN_HOME
        {
            get { return cygwinHome; }
            set { cygwinHome = value; }
        } string cygwinHome;

        public string BRICKOS_HOME
        {
            get { return brickOSHome; }
            set { brickOSHome = value; }
        } string brickOSHome;

        public string XC_TOOLS_HOME
        {
            get { return xcToolsHome; }
            set { xcToolsHome=value; }
        }string xcToolsHome;

        public string INC_DIRS
        {
            get { return incDirs; }
            set { incDirs = value; }
        } string incDirs;

        public string[] SRC_FILES
        {
            get { return srcFiles; }
            set { srcFiles = value; }
        } string[] srcFiles;

        public string TARGET
        {
            get { return target; }
            set { target = value; }
        } string target;

        public string FLAG_CC
        {
            get { return flagCC; }
            set { flagCC = value; }
        } string flagCC;
        #endregion

        public string Generate()
        {
            StringBuilder sb = new StringBuilder();
            TextWriter writer = new StringWriter(sb);

            writer.WriteLine("################################################################################");
            writer.WriteLine("#");
            writer.WriteLine("# makefile of closs compiler for BrickOS");
            writer.WriteLine("# Generated by VsPackageCompileNMake on " + System.DateTime.Now.ToString()); 
            writer.WriteLine("#");
            writer.WriteLine("################################################################################");
            writer.WriteLine("# Author: Hiroki Yagita");
            writer.WriteLine("# Author: Hiroshi Ota");

            writer.WriteLine();
            writer.WriteLine("CYGWIN_HOME=" + cygwinHome);
            writer.WriteLine("BRICKOS_HOME=" + brickOSHome);
            writer.WriteLine("XC_HOME=" + xcToolsHome);
            writer.WriteLine("XC_TOOL_PATH=$(XC_HOME)\\bin");
            writer.WriteLine();
            writer.WriteLine("H8300_HMS=h8300-hitachi-hms-");
         //   writer.WriteLine("H8300_HMS_=");
            writer.WriteLine("CC=$(XC_TOOL_PATH)\\$(H8300_HMS)g++");
            writer.WriteLine("LD=$(XC_TOOL_PATH)\\$(H8300_HMS)ld");
            writer.WriteLine("CPPFLAGS_DEFS= -D_BRICKOS_");
            writer.WriteLine("CPPFLAGS_STDINC= -I. -I$(BRICKOS_HOME)\\include -I$(BRICKOS_HOME)\\include\\lnp -I$(BRICKOS_HOME)\\boot");
            writer.WriteLine("CPPFLAGS_PROJINC= " + incDirs);
            writer.WriteLine("CPPFLAGS= $(CPPFLAGS_DEFS) $(CPPFLAGS_STDINC) $(CPPFLAGS_PROJINC)");
            writer.WriteLine("CFLAGS= -O2 -fno-rtti -fno-exceptions -fno-builtin -fomit-frame-pointer -Wall");
            writer.WriteLine();
            writer.WriteLine("path=%path%;$(XC_TOOL_PATH);$(CYGWIN_HOME)\\bin");
            writer.WriteLine();
            writer.WriteLine("OUTDIR=Release");

            StringBuilder bufSrc = new StringBuilder();
            StringBuilder bufObj = new StringBuilder();
            for (int i = 0; i < srcFiles.Length; i++)
            {
                if (i > 0)
                {
                    bufSrc.Append(" ");
                    bufObj.Append(" ");
                }
                bufSrc.Append(srcFiles[i]);
                bufObj.Append("$(OUTDIR)\\" + srcFiles[i].Replace(".cpp", ".o"));
            }

            writer.WriteLine("TARGET=$(OUTDIR)\\" + target + ".obj");
            writer.WriteLine("SRCS=" + bufSrc.ToString());
            writer.WriteLine("OBJS=" + bufObj.ToString());
            writer.WriteLine();
            writer.WriteLine("all: depend $(TARGET)");
            writer.WriteLine();
            writer.WriteLine("depend:");
            writer.WriteLine("  $(CC) -M $(CPPFLAGS) $(SRCS) > .depend");
            writer.WriteLine("  if not exist \"$(OUTDIR)\" (mkdir $(OUTDIR))");
            writer.WriteLine();
            writer.WriteLine("clean:");
            writer.WriteLine("  del $(TARGET) $(OBJS)");
            writer.WriteLine("  rmdir $(OUTDIR)");
            writer.WriteLine();
            writer.WriteLine("$(TARGET): $(OBJS)");
            writer.WriteLine("	$(LD) -r -o $(TARGET) $(OBJS)");
            writer.WriteLine();
            writer.WriteLine("#{}.cpp{$(OUTDIR)\\\\}.o:");
            writer.WriteLine("#	$(CC) $(CFLAGS) -c -o $$@ $< ");

            for (int i = 0; i < srcFiles.Length; i++)
            {
                string objName = getObjFileName(srcFiles[i]);
                writer.WriteLine("$(OUTDIR)\\" + objName + ":	" + srcFiles[i]);
                writer.WriteLine("	$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(OUTDIR)\\" + objName + "  " + srcFiles[i]);
            }

            return sb.ToString();
        }

        private string getObjFileName(string srcFile)
        {
            int pos = srcFile.LastIndexOf(".");
            string objName = srcFile.Replace(".cpp", ".o");
            return objName;
        }
    }
}
